import 'dart:async';

import 'package:commons/commons.dart';
import 'package:wechat_kit/wechat_kit.dart';
import 'package:wechat_kit_extension/wechat_kit_extension.dart';

class WxMan extends GetxController {
  late final StreamSubscription<WechatResp> _respSubs;

  Completer<WechatUserInfoResp?>? loginCompleter;
  Completer<WechatPayResp?>? payCompleter;

  Future<bool> isInstalled() {
    return WechatKitPlatform.instance.isInstalled();
  }

  ///登录
  Future<WechatUserInfoResp?> login() async {
    loginCompleter = Completer<WechatUserInfoResp?>();

    await WechatKitPlatform.instance.auth(
      scope: <String>[WechatScope.kSNSApiUserInfo],
      state: 'auth',
    );

    return loginCompleter?.future;
  }

  Future<void> share(
      {required int scene,
      required String title,
      required String desc,
      required String webpageUrl}) {
    return WechatKitPlatform.instance.shareWebpage(
      scene: scene,
      title: title,
      description: desc,
      webpageUrl: webpageUrl,
    );
  }

  Future<WechatPayResp?> pay(
      {required String prepayId,
      required String nonceStr,
      required String timeStamp,
      required String sign}) {
    payCompleter = Completer<WechatPayResp?>();
    WechatKitPlatform.instance.pay(
      appId: AppConfig.wxAppId,
      partnerId: '商户号',
      prepayId: '预支付交易会话ID',
      package: '扩展字段,暂填写固定值：Sign=WXPay',
      nonceStr: '随机字符串, 随机字符串，不长于32位',
      timeStamp: '时间戳：东八区，单位秒',
      sign: '签名',
    );
    return payCompleter!.future;
  }

  @override
  void onInit() {
    _respSubs =
        WechatKitPlatform.instance.respStream().listen(_listener); // 订阅消息
    WechatKitPlatform.instance.registerApp(
      appId: AppConfig.wxAppId,
      universalLink: AppConfig.universalLink,
    );
    super.onInit();
  }

  void _listener(resp) {
    if (resp is WechatAuthResp) {
      final String content = 'auth: ${resp.errorCode} ${resp.errorMsg}';
      Get.log('登录$content');
      _loginResp(resp);
    } else if (resp is WechatShareMsgResp) {
      final String content = 'share: ${resp.errorCode} ${resp.errorMsg}';
      Get.log('分享$content');
    } else if (resp is WechatPayResp) {
      final String content = 'pay: ${resp.errorCode} ${resp.errorMsg}';
      Get.log('支付$content');
      payCompleter?.complete(resp);
    } else if (resp is WechatLaunchMiniProgramResp) {
      final String content = 'mini program: ${resp.errorCode} ${resp.errorMsg}';
      Get.log('拉起小程序$content');
    }
  }

  void _loginResp(WechatAuthResp resp) async {
    if (resp.isSuccessful) {
      final WechatAccessTokenResp accessTokenResp =
          await WechatExtension.getAccessTokenUnionID(
        appId: AppConfig.wxAppId,
        appSecret: AppConfig.wxAppSecret,
        code: resp.code!,
      );
      if (accessTokenResp.isSuccessful) {
        final WechatUserInfoResp userInfoResp =
            await WechatExtension.getUserInfoUnionID(
          openId: accessTokenResp.openid!,
          accessToken: accessTokenResp.accessToken!,
        );
        if (userInfoResp.isSuccessful) {
          if (loginCompleter != null && !loginCompleter!.isCompleted) {
            loginCompleter?.complete(userInfoResp);
            return;
          }
        }
      }
    }
    loginCompleter?.complete(null);
  }

  @override
  void onClose() {
    _respSubs.cancel();
    loginCompleter?.complete(null);
    super.onClose();
  }
}

extension WxEx on GetInterface {
  WxMan get wx => find<WxMan>();
}
